home *** CD-ROM | disk | FTP | other *** search
- ///////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // This example code is from the book:
- //
- // Object-Oriented Programming with C++ and OSF/Motif
- // by
- // Douglas Young
- // Prentice Hall, 1992
- // ISBN 0-13-630252-1
- //
- // Copyright 1991 by Prentice Hall
- // All Rights Reserved
- //
- // Permission to use, copy, modify, and distribute this software for
- // any purpose except publication and without fee is hereby granted, provided
- // that the above copyright notice appear in all copies of the software.
- ///////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
-
-
- //////////////////////////////////////////////////////////
- // Stage.C
- //////////////////////////////////////////////////////////
- #include "Application.h"
- #include "Stage.h"
- #include "Actor.h"
- #include <Xm/DrawingA.h>
-
- Stage::Stage ( Widget parent, char *name ) : UIComponent( name )
- {
- XGCValues gcv;
-
- // Initialize all data members
-
- _front = NULL;
- _back = NULL;
- _nActors = 0;
- _cast = NULL;
-
- // Create the visible drawing canvas, and set
- // up the destruction handler
-
- _w = XtCreateWidget ( _name,
- xmDrawingAreaWidgetClass,
- parent,
- NULL, 0 );
-
- installDestroyHandler();
-
- // Add callbacks to handle resizing and exposures
-
- XtAddCallback ( _w, XmNresizeCallback,
- &Stage::resizeCallback,
- (XtPointer) this );
- XtAddCallback ( _w, XmNexposeCallback,
- &Stage::redisplayCallback,
- (XtPointer) this );
-
- // A graphics context is need for copying the pixmap buffers and
- // erasing the back pixmap. Use the background color of
- // the base widget for the fill color.
-
- XtVaGetValues ( _w,
- XmNbackground, &gcv.foreground,
- NULL );
-
- _gc = XtGetGC ( _w, GCForeground, &gcv );
-
- // Call resize to create the first pixmaps.
-
- resize();
- }
-
- Stage::~Stage()
- {
- // Free the pixmaps and GC, if they still exist
-
- if ( _front )
- XFreePixmap ( XtDisplay ( _w ), _front );
-
- if ( _back )
- XFreePixmap ( XtDisplay ( _w ), _back );
-
- if ( _w && _gc )
- XtReleaseGC ( _w, _gc );
- }
-
- void Stage::resizeCallback ( Widget,
- XtPointer clientData,
- XtPointer )
- {
- Stage *obj = (Stage *) clientData;
- obj->resize();
- }
-
- void Stage::resize()
- {
- // Get the current size of the drawing area
-
- XtVaGetValues ( _w,
- XmNwidth, &_width,
- XmNheight, &_height,
- NULL );
-
- // Pixmaps can't be resized, so just destroy the old ones
-
- if ( _front )
- XFreePixmap ( XtDisplay ( _w ), _front );
-
- if ( _back )
- XFreePixmap ( XtDisplay ( _w ), _back );
-
- // Create new pixmaps to match the new size of the window
-
- _back = XCreatePixmap ( XtDisplay ( _w ),
- DefaultRootWindow ( XtDisplay ( _w ) ),
- _width, _height,
- DefaultDepthOfScreen ( XtScreen ( _w ) ) );
-
- _front = XCreatePixmap ( XtDisplay ( _w ),
- DefaultRootWindow ( XtDisplay ( _w ) ),
- _width, _height,
- DefaultDepthOfScreen ( XtScreen ( _w ) ) );
-
- // Erase both pixmaps
-
- XFillRectangle ( XtDisplay ( _w ), _back,
- _gc, 0, 0, _width, _height );
- XFillRectangle ( XtDisplay ( _w ), _front,
- _gc, 0, 0, _width, _height );
- }
-
- void Stage::nextFrame()
- {
- // For each new frame, simply swap buffers and
- // ask each Actor object to draw its next frame
- // in the back buffer.
-
- swapBuffers();
-
- for ( int i = 0; i < _nActors; i++)
- _cast[i]->nextFrame ( _back, _width, _height );
- }
-
- void Stage::swapBuffers()
- {
- // Switch the front and back buffers
-
- if ( XtIsRealized ( _w ) )
- {
- Pixmap tmp;
-
- // Do the swap
-
- tmp = _front;
- _front = _back;
- _back = tmp;
-
- // Copy the new fron buffer to the drawing area
-
- XCopyArea ( XtDisplay ( _w ), _front, XtWindow ( _w ),
- _gc, 0, 0, _width, _height, 0, 0 );
-
- // Erase the new back buffer to get ready for the next scene
-
- XFillRectangle ( XtDisplay ( _w ), _back,
- _gc, 0, 0, _width, _height );
- }
- }
-
- void Stage::redisplayCallback ( Widget,
- XtPointer clientData,
- XtPointer )
- {
- Stage *obj = (Stage *) clientData;
- obj->redisplay();
- }
-
- void Stage::redisplay ( )
- {
- // Copy the contents of the front pixmap
- // to restore the window
-
- XCopyArea ( theApplication->display(), _front,
- XtWindow ( _w ), _gc, 0, 0,
- _width, _height, 0, 0 );
- }
-
- void Stage::addActor ( Actor *newActor )
- {
- int i;
-
- Actor **newList;
-
- // Allocate a new list large enough to hold
- // one more object
-
- newList = new Actor*[_nActors + 1];
-
- // Copy the old list to the new
-
- for ( i = 0; i < _nActors; i++ )
- newList[i] = _cast[i];
-
- // Add the new object to the end of the list
-
- newList[_nActors] = newActor;
-
- // delete the old list and make _cast
- // point to the new list
-
- delete _cast;
- _cast = newList;
-
-
- _nActors++;
- }
-
- void Stage::removeActor( Actor *oldActor )
- {
- int i, j;
- Boolean found = FALSE;
- Actor **newList;
-
- // remove the given Actor from the list
-
- for ( i = 0; i < _nActors; i++ )
- if ( _cast[i] == oldActor )
- {
- found = TRUE;
- for ( j = i; j < _nActors-1; j++ )
- _cast[j] = _cast[j+1];
- break;
- }
-
- if ( !found )
- return;
-
- _nActors--;
-
- // Allocate a new, smaller list
-
- newList = new Actor*[_nActors];
-
- for ( i = 0; i < _nActors; i++ )
- newList[i] = _cast[i];
-
- delete _cast;
- _cast = newList;
- }
-